﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;

public partial class PostFXStack
{

    enum Pass
    {
        Copy,
        BloomHorizontal,
        BloomVertical,
        BloomCombineAdd,
        BloomPrefilter,
        BloomPrefilterFireflies,
        BloomCombineScatter,
        BloomCombineScatterFinal,

        ToneMappingNone,        
        ToneMappingReinhard,
        ToneMappingNeutral,
        ToneMappingACES,
        ColorGradingNone,
        ColorGradingReinhard,
        ColorGradingNeutral,
        ColorGradingACES,

        Final,

    };



    const string bufferName = "Post FX";

    CommandBuffer buffer = new CommandBuffer
    {
        name = bufferName,
    };

    ScriptableRenderContext context;
    Camera camera;

    PostFXSettings settings;

    bool useHDR;
    int colorLUTResolution;


    int fxSourceId = Shader.PropertyToID("_PostFXSource");
    int fxSource2Id = Shader.PropertyToID("_PostFXSource2");
    int bloomBicubicUpsamplingId = Shader.PropertyToID("_BloomBicubicUpsampling");
    int bloomPrefilterId = Shader.PropertyToID("_BloomPrefilter");
    int bloomThresholdId = Shader.PropertyToID("_BloomThreshold");
    int bloomIntensityId = Shader.PropertyToID("_BloomIntensity");
    int bloomResultId = Shader.PropertyToID("_BloomResult");

    //float4 _ColorAdjustments;
    //float4 _ColorFilter;
    int _ColorAdjustmentsId = Shader.PropertyToID("_ColorAdjustments");
    int _ColorFilterId = Shader.PropertyToID("_ColorFilter");
    int _WhiteBalanceId = Shader.PropertyToID("_WhiteBalance");
    //float4 _SplitToningShadows, _SplitToningHighlights;
    int _SplitToningShadowsId = Shader.PropertyToID("_SplitToningShadows");
    int _SplitToningHighlightsId = Shader.PropertyToID("_SplitToningHighlights");

    int _ChannelMixerRedId = Shader.PropertyToID("_ChannelMixerRed");
    int _ChannelMixerGreenId = Shader.PropertyToID("_ChannelMixerGreen");
    int _ChannelMixerBlueId = Shader.PropertyToID("_ChannelMixerBlue");

    //float4 _SMHShadows, _SMHMidtones, _SMHHightlights, _SMHRange;
    int _SMHShadowsId = Shader.PropertyToID("_SMHShadows");
    int _SMHMidtonesId = Shader.PropertyToID("_SMHMidtones");
    int _SMHHightlightsId = Shader.PropertyToID("_SMHHightlights");
    int _SMHRangeId = Shader.PropertyToID("_SMHRange");

    
    int _ColorGradingLUTId = Shader.PropertyToID("_ColorGradingLUT");
    int _ColorGradingLUTParametersId = Shader.PropertyToID("_ColorGradingLUTParameters");
    int _ColorGradingLUTInLogCId = Shader.PropertyToID("_ColorGradingLUTInLogC");
    




    int bloomPyramidId;

  //  int colorGradingLUTId;

    const int maxBloomPyramidLevels = 16;

    public bool IsActive => settings != null;


    partial void ApplySceneViewState();

    public PostFXStack()
    {
        bloomPyramidId = Shader.PropertyToID("_BloomPyramid0");
        for (int i = 0; i < maxBloomPyramidLevels * 2; i++)
        {
            Shader.PropertyToID("_BloomPyramid" + i);
        }
    }

    public void Setup(
        ScriptableRenderContext context,
        Camera camera,
        PostFXSettings settings,
        bool useHDR,
        int colorLUTResolution
        )
    {
        this.context = context;
        this.camera = camera;
        this.settings = camera.cameraType <= CameraType.SceneView ? settings : null;
        this.useHDR = useHDR;
        this.colorLUTResolution = colorLUTResolution;

        this.ApplySceneViewState();
    }

    public void Render(int sourceId)
    {
        // buffer.Blit(sourceId, BuiltinRenderTextureType.CameraTarget);
        // Draw(sourceId, BuiltinRenderTextureType.CameraTarget, Pass.Copy);
        //DoBloom2(sourceId);
        if(DoBloom6(sourceId))
        {
            DoColorGradingAndToneMapping(bloomResultId);
            buffer.ReleaseTemporaryRT(bloomResultId);
        }
        else
        {
            DoColorGradingAndToneMapping(sourceId);
        }
        ExecuteBuffer();
    }

    void DoBloom(int sourceId)
    {
        buffer.BeginSample("Bloom");
        int width = camera.pixelWidth / 2, height = camera.pixelHeight / 2;
        PostFXSettings.BloomSettings bloom = settings.Bloom;
        RenderTextureFormat format = RenderTextureFormat.Default;
        int fromId = sourceId, toId = bloomPyramidId;

        int i;

        for (i = 0; i < bloom.maxIterations; i++)
        {
            if (height < bloom.downscaleLimit || width < bloom.downscaleLimit)
            {
                break;
            }

            buffer.GetTemporaryRT(toId, width, height, 0, FilterMode.Bilinear, format);
            Draw(fromId, toId, Pass.BloomHorizontal);
            fromId = toId;
            toId += 1;
            width /= 2;
            height /= 2;
        }

        Draw(fromId, BuiltinRenderTextureType.CameraTarget, Pass.Copy);

        for (i -= 1; i >= 0; i--)
        {
            buffer.ReleaseTemporaryRT(bloomPyramidId + i);
        }
        buffer.EndSample("Bloom");
    }


    //高斯过滤
    void DoBloom2(int sourceId)
    {
        buffer.BeginSample("Bloom");
        int width = camera.pixelWidth / 2, height = camera.pixelHeight / 2;
        PostFXSettings.BloomSettings bloom = settings.Bloom;
        RenderTextureFormat format = RenderTextureFormat.Default;
        int fromId = sourceId, toId = bloomPyramidId + 1;

        int i;

        for (i = 0; i < bloom.maxIterations; i++)
        {
            if (height < bloom.downscaleLimit || width < bloom.downscaleLimit)
            {
                break;
            }
            int midId = toId - 1;
            buffer.GetTemporaryRT(midId, width, height, 0, FilterMode.Bilinear, format);
            buffer.GetTemporaryRT(toId, width, height, 0, FilterMode.Bilinear, format);
            Draw(fromId, midId, Pass.BloomHorizontal);
            Draw(midId, toId, Pass.BloomVertical);
            fromId = toId;
            toId += 2;
            width /= 2;
            height /= 2;
        }

        Draw(fromId, BuiltinRenderTextureType.CameraTarget, Pass.Copy);

        for (i -= 1; i >= 0; i--)
        {
            buffer.ReleaseTemporaryRT(fromId);
            buffer.ReleaseTemporaryRT(fromId - 1);
            fromId -= 2;
        }
        buffer.EndSample("Bloom");
    }

    //叠加模糊
    void DoBloom3(int sourceId)
    {
        buffer.BeginSample("Bloom");
        int width = camera.pixelWidth / 2, height = camera.pixelHeight / 2;
        PostFXSettings.BloomSettings bloom = settings.Bloom;

        if (bloom.maxIterations == 0 || height < bloom.downscaleLimit || width < bloom.downscaleLimit)
        {
            Draw(sourceId, BuiltinRenderTextureType.CameraTarget, Pass.Copy);
            buffer.EndSample("Bloom");
            return;
        }

        RenderTextureFormat format = RenderTextureFormat.Default;
        int fromId = sourceId, toId = bloomPyramidId + 1;

        int i;
        for (i = 0; i < bloom.maxIterations; i++)
        {
            if (height < bloom.downscaleLimit || width < bloom.downscaleLimit)
            {
                break;
            }
            int midId = toId - 1;
            buffer.GetTemporaryRT(midId, width, height, 0, FilterMode.Bilinear, format);
            buffer.GetTemporaryRT(toId, width, height, 0, FilterMode.Bilinear, format);
            Draw(fromId, midId, Pass.BloomHorizontal);
            Draw(midId, toId, Pass.BloomVertical);
            fromId = toId;
            toId += 2;
            width /= 2;
            height /= 2;
        }

        if(i > 1)
        {
            // Draw(fromId, BuiltinRenderTextureType.CameraTarget, Pass.Copy);
            buffer.ReleaseTemporaryRT(fromId - 1);
            toId -= 5;

            buffer.SetGlobalFloat(bloomBicubicUpsamplingId, bloom.bicubicUpsampling ? 1f : 0f);
            for (i -= 1; i > 0; i--)
            {
                buffer.SetGlobalTexture(fxSource2Id, toId + 1);
                Draw(fromId, toId, Pass.BloomCombineAdd);
                buffer.ReleaseTemporaryRT(fromId);
                buffer.ReleaseTemporaryRT(toId + 1);
                fromId = toId;
                toId -= 2;
            }
        }
        else
        {
            buffer.ReleaseTemporaryRT(bloomPyramidId);
        }
       
        buffer.SetGlobalTexture(fxSource2Id, sourceId);
        Draw(fromId, BuiltinRenderTextureType.CameraTarget, Pass.BloomCombineAdd);
        buffer.ReleaseTemporaryRT(fromId);
        buffer.EndSample("Bloom");
    }


    //叠加模糊减半分辨率
    void DoBloom4(int sourceId)
    {
        buffer.BeginSample("Bloom");
        int width = camera.pixelWidth / 2, height = camera.pixelHeight / 2;
        PostFXSettings.BloomSettings bloom = settings.Bloom;

        if (bloom.maxIterations == 0 || height < bloom.downscaleLimit * 2 || width < bloom.downscaleLimit * 2)
        {
            Draw(sourceId, BuiltinRenderTextureType.CameraTarget, Pass.Copy);
            buffer.EndSample("Bloom");
            return;
        }

        RenderTextureFormat format = RenderTextureFormat.Default;
        buffer.GetTemporaryRT(bloomPrefilterId, width, height, 0, FilterMode.Bilinear, format);
        Draw(sourceId, bloomPrefilterId, Pass.Copy);
        width /= 2;
        height /= 2;

        int fromId = bloomPrefilterId, toId = bloomPyramidId + 1;

        int i;
        for (i = 0; i < bloom.maxIterations; i++)
        {
            if (height < bloom.downscaleLimit || width < bloom.downscaleLimit)
            {
                break;
            }
            int midId = toId - 1;
            buffer.GetTemporaryRT(midId, width, height, 0, FilterMode.Bilinear, format);
            buffer.GetTemporaryRT(toId, width, height, 0, FilterMode.Bilinear, format);
            Draw(fromId, midId, Pass.BloomHorizontal);
            Draw(midId, toId, Pass.BloomVertical);
            fromId = toId;
            toId += 2;
            width /= 2;
            height /= 2;
        }
        buffer.ReleaseTemporaryRT(bloomPrefilterId);

        if (i > 1)
        {
            // Draw(fromId, BuiltinRenderTextureType.CameraTarget, Pass.Copy);
            buffer.ReleaseTemporaryRT(fromId - 1);
            toId -= 5;

            buffer.SetGlobalFloat(bloomBicubicUpsamplingId, bloom.bicubicUpsampling ? 1f : 0f);
            for (i -= 1; i > 0; i--)
            {
                buffer.SetGlobalTexture(fxSource2Id, toId + 1);
                Draw(fromId, toId, Pass.BloomCombineAdd);
                buffer.ReleaseTemporaryRT(fromId);
                buffer.ReleaseTemporaryRT(toId + 1);
                fromId = toId;
                toId -= 2;
            }
        }
        else
        {
            buffer.ReleaseTemporaryRT(bloomPyramidId);
        }

        buffer.SetGlobalTexture(fxSource2Id, sourceId);
        Draw(fromId, BuiltinRenderTextureType.CameraTarget, Pass.BloomCombineAdd);
        buffer.ReleaseTemporaryRT(fromId);
        buffer.EndSample("Bloom");
    }

    //叠加模糊减半分辨率，阈值
    void DoBloom5(int sourceId)
    {
        buffer.BeginSample("Bloom");
        PostFXSettings.BloomSettings bloom = settings.Bloom;

        Vector4 threshold;
        threshold.x = Mathf.GammaToLinearSpace(bloom.threshold);
        threshold.y = threshold.x * bloom.thresholdKnee;
        threshold.z = 2f * threshold.y;
        threshold.w = 0.25f / (threshold.y + 0.00001f);
        threshold.y -= threshold.x;
        buffer.SetGlobalVector(bloomThresholdId, threshold);

        int width = camera.pixelWidth / 2, height = camera.pixelHeight / 2;
       

        if (bloom.maxIterations == 0 || height < bloom.downscaleLimit * 2 || width < bloom.downscaleLimit * 2)
        {
            Draw(sourceId, BuiltinRenderTextureType.CameraTarget, Pass.Copy);
            buffer.EndSample("Bloom");
            return;
        }

        RenderTextureFormat format = RenderTextureFormat.Default;
        buffer.GetTemporaryRT(bloomPrefilterId, width, height, 0, FilterMode.Bilinear, format);
        Draw(sourceId, bloomPrefilterId, Pass.BloomPrefilter);
        width /= 2;
        height /= 2;

        int fromId = bloomPrefilterId, toId = bloomPyramidId + 1;

        int i;
        for (i = 0; i < bloom.maxIterations; i++)
        {
            if (height < bloom.downscaleLimit || width < bloom.downscaleLimit)
            {
                break;
            }
            int midId = toId - 1;
            buffer.GetTemporaryRT(midId, width, height, 0, FilterMode.Bilinear, format);
            buffer.GetTemporaryRT(toId, width, height, 0, FilterMode.Bilinear, format);
            Draw(fromId, midId, Pass.BloomHorizontal);
            Draw(midId, toId, Pass.BloomVertical);
            fromId = toId;
            toId += 2;
            width /= 2;
            height /= 2;
        }
        buffer.ReleaseTemporaryRT(bloomPrefilterId);

        if (i > 1)
        {
            // Draw(fromId, BuiltinRenderTextureType.CameraTarget, Pass.Copy);
            buffer.ReleaseTemporaryRT(fromId - 1);
            toId -= 5;

            buffer.SetGlobalFloat(bloomBicubicUpsamplingId, bloom.bicubicUpsampling ? 1f : 0f);
            for (i -= 1; i > 0; i--)
            {
                buffer.SetGlobalTexture(fxSource2Id, toId + 1);
                Draw(fromId, toId, Pass.BloomCombineAdd);
                buffer.ReleaseTemporaryRT(fromId);
                buffer.ReleaseTemporaryRT(toId + 1);
                fromId = toId;
                toId -= 2;
            }
        }
        else
        {
            buffer.ReleaseTemporaryRT(bloomPyramidId);
        }

        buffer.SetGlobalTexture(fxSource2Id, sourceId);
        Draw(fromId, BuiltinRenderTextureType.CameraTarget, Pass.BloomCombineAdd);
        buffer.ReleaseTemporaryRT(fromId);
        buffer.EndSample("Bloom");
    }


    //叠加模糊减半分辨率，阈值，强度
    bool DoBloom6(int sourceId)
    {
        buffer.BeginSample("Bloom");
        PostFXSettings.BloomSettings bloom = settings.Bloom;

        Vector4 threshold;
        threshold.x = Mathf.GammaToLinearSpace(bloom.threshold);
        threshold.y = threshold.x * bloom.thresholdKnee;
        threshold.z = 2f * threshold.y;
        threshold.w = 0.25f / (threshold.y + 0.00001f);
        threshold.y -= threshold.x;
        buffer.SetGlobalVector(bloomThresholdId, threshold);

        int width = camera.pixelWidth / 2, height = camera.pixelHeight / 2;


        if (bloom.maxIterations == 0 ||bloom.intensity <= 0f ||  height < bloom.downscaleLimit * 2 || width < bloom.downscaleLimit * 2)
        {
           // Draw(sourceId, BuiltinRenderTextureType.CameraTarget, Pass.Copy);
            buffer.EndSample("Bloom");
            return false;
        }

        RenderTextureFormat format =this.useHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;
        buffer.GetTemporaryRT(bloomPrefilterId, width, height, 0, FilterMode.Bilinear, format);
        Draw(sourceId, bloomPrefilterId,bloom.fadeFireflies ? Pass.BloomPrefilterFireflies : Pass.BloomPrefilter);
        width /= 2;
        height /= 2;

        int fromId = bloomPrefilterId, toId = bloomPyramidId + 1;

        int i;
        for (i = 0; i < bloom.maxIterations; i++)
        {
            if (height < bloom.downscaleLimit || width < bloom.downscaleLimit)
            {
                break;
            }
            int midId = toId - 1;
            buffer.GetTemporaryRT(midId, width, height, 0, FilterMode.Bilinear, format);
            buffer.GetTemporaryRT(toId, width, height, 0, FilterMode.Bilinear, format);
            Draw(fromId, midId, Pass.BloomHorizontal);
            Draw(midId, toId, Pass.BloomVertical);
            fromId = toId;
            toId += 2;
            width /= 2;
            height /= 2;
        }
        buffer.ReleaseTemporaryRT(bloomPrefilterId);

        
        Pass combinePass,finalPass;
        float finalIntensity;
        if(bloom.mode == PostFXSettings.BloomSettings.Mode.Additive)
        {
            finalPass = combinePass = Pass.BloomCombineAdd;
            buffer.SetGlobalFloat(bloomIntensityId, 1);
            finalIntensity = bloom.intensity;
        }
        else
        {
            combinePass = Pass.BloomCombineScatter;
            finalPass = Pass.BloomCombineScatterFinal;
            buffer.SetGlobalFloat(bloomIntensityId, bloom.scatter);
            finalIntensity = Mathf.Min(bloom.intensity, 0.95f);
        }
        if (i > 1)
        {
            // Draw(fromId, BuiltinRenderTextureType.CameraTarget, Pass.Copy);
            buffer.ReleaseTemporaryRT(fromId - 1);
            toId -= 5;
            buffer.SetGlobalFloat(bloomBicubicUpsamplingId, bloom.bicubicUpsampling ? 1f : 0f);
            for (i -= 1; i > 0; i--)
            {
                buffer.SetGlobalTexture(fxSource2Id, toId + 1);
                Draw(fromId, toId, combinePass);
                buffer.ReleaseTemporaryRT(fromId);
                buffer.ReleaseTemporaryRT(toId + 1);
                fromId = toId;
                toId -= 2;
            }
        }
        else
        {
            buffer.ReleaseTemporaryRT(bloomPyramidId);
        }
        buffer.SetGlobalFloat(bloomIntensityId, finalIntensity);
        buffer.SetGlobalTexture(fxSource2Id, sourceId);
        buffer.GetTemporaryRT(bloomResultId,
            camera.pixelWidth,
            camera.pixelHeight,
            0,
            FilterMode.Bilinear,
            format
            );
        Draw(fromId, bloomResultId, finalPass);
        buffer.ReleaseTemporaryRT(fromId);
        buffer.EndSample("Bloom");
        return true;
    }
    void DoToneMapping(int sourceId)
    {
        PostFXSettings.ToneMappingSettings toneMapping = this.settings.ToneMapping;

        //Pass pass = toneMapping.mode < 0 ? Pass.Copy : Pass.ToneMappingReinhard + (int)toneMapping.mode ;
        Pass pass = Pass.ToneMappingNone + (int)toneMapping.mode;      
        Draw(sourceId, BuiltinRenderTextureType.CameraTarget, pass);

       
    }
    void ConfigureColorAdjustments()
    {
        PostFXSettings.ColorAdjustmentsSettings colorAdjustments = settings.ColorAdjustments;
        buffer.SetGlobalVector(_ColorAdjustmentsId, new Vector4(
            Mathf.Pow(2f, colorAdjustments.postExposure),
            colorAdjustments.constrast * 0.01f + 1f,
            colorAdjustments.hueShift * (1f / 360f),
            colorAdjustments.saturation * 0.01f + 1f
            ));
        buffer.SetGlobalColor(_ColorFilterId, colorAdjustments.colorFilter.linear);

    }

    void ConfigureWhiteBalance()
    {
        PostFXSettings.WhiteBalanceSettings whiteBalance = this.settings.WhiteBalance;

        Vector3 color = ColorUtils.ColorBalanceToLMSCoeffs(whiteBalance.temperature,
            whiteBalance.tint);
        buffer.SetGlobalVector(_WhiteBalanceId,color);

        
    }
    void ConfigureSplitToning()
    {
        PostFXSettings.SplitToningSettings splitToning = this.settings.SplitToning;
        Color splitColor = splitToning.shadows;
        splitColor.a = splitToning.balance * 0.01f;
        buffer.SetGlobalColor(_SplitToningShadowsId, splitColor);
        buffer.SetGlobalColor(_SplitToningHighlightsId, splitToning.highlights);
    }

    void ConfigureChannelMixer()
    {
        PostFXSettings.ChannelMixerSettings channelMixer = this.settings.ChannelMixer;
        buffer.SetGlobalVector(_ChannelMixerRedId, channelMixer.red);
        buffer.SetGlobalVector(_ChannelMixerGreenId, channelMixer.green);
        buffer.SetGlobalVector(_ChannelMixerBlueId, channelMixer.blue);
    }

    void ConfigureShadowsMidtonesHighlights()
    {
        PostFXSettings.ShadowsMidtonesHightlightsSettings settings1 = this.settings.ShadowsMidtonesHightlights;

        buffer.SetGlobalColor(_SMHShadowsId, settings1.shadows.linear);
        buffer.SetGlobalColor(_SMHMidtonesId, settings1.midtones.linear);
        buffer.SetGlobalColor(_SMHHightlightsId, settings1.hightlights.linear);
        buffer.SetGlobalVector(_SMHRangeId,new Vector4( settings1.shadowStart, settings1.shadowsEnd,
            settings1.hightlightsStart,settings1.hightlightsEnd)
            );
    }
    void DoColorGradingAndToneMapping(int sourceId)
    {
        ConfigureColorAdjustments();
        ConfigureWhiteBalance();
        ConfigureSplitToning();
        ConfigureChannelMixer();
        ConfigureShadowsMidtonesHighlights();

        PostFXSettings.ToneMappingSettings toneMapping = this.settings.ToneMapping;
       

        int lutHeight = colorLUTResolution;
        int lutWidth = lutHeight * lutHeight;
        buffer.GetTemporaryRT(_ColorGradingLUTId, lutWidth, lutHeight, 0,
            FilterMode.Bilinear,RenderTextureFormat.DefaultHDR
            );
        /* */
        buffer.SetGlobalVector(_ColorGradingLUTParametersId, new Vector4(
            lutHeight,
            0.5f/lutWidth,
            0.5f/lutHeight,
            lutHeight/(lutHeight - 1)
            ));

        // Pass pass = toneMapping.mode < 0 ? Pass.Copy : Pass.ToneMappingReinhard + (int)toneMapping.mode ;
        // Pass pass = Pass.ToneMappingNone + (int)toneMapping.mode;
        // Draw(sourceId, BuiltinRenderTextureType.CameraTarget, pass);
        Pass pass = Pass.ColorGradingNone + (int)toneMapping.mode;
        buffer.SetGlobalFloat(_ColorGradingLUTInLogCId, (this.useHDR && pass != Pass.ColorGradingNone ) ? 1f : 0f);
        Draw(sourceId, _ColorGradingLUTId, pass);


        //---
        /*  */
        buffer.SetGlobalVector(_ColorGradingLUTParametersId, new Vector4(
         1f / lutWidth,
         1f / lutHeight,
         lutHeight - 1
         ));
      
        Draw(sourceId, BuiltinRenderTextureType.CameraTarget, Pass.Final);
        buffer.ReleaseTemporaryRT(_ColorGradingLUTId);

        //DrawFinal(sourceId, pass);
    }
    void Draw(
        RenderTargetIdentifier from,
        RenderTargetIdentifier to,
        Pass pass 
        )
    {
        buffer.SetGlobalTexture(fxSourceId, from);
        buffer.SetRenderTarget(to, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);

        buffer.DrawProcedural(
            Matrix4x4.identity,
            settings.Material,
            (int)pass,
            MeshTopology.Triangles,
            3
            );
    }
    void DrawFinal(
       RenderTargetIdentifier from   ,
        Pass pass
       )
    {
        buffer.SetGlobalTexture(fxSourceId, from);
        buffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);
        buffer.SetViewport(this.camera.pixelRect);
        buffer.DrawProcedural(
            Matrix4x4.identity,
            settings.Material,
            //(int)Pass.Final,
            (int)pass,
            MeshTopology.Triangles,
            3
            );
    }
    void ExecuteBuffer()
    {
        context.ExecuteCommandBuffer(buffer);
        buffer.Clear();
    }

}
